package com.youku.core.view.components
{
   import com.youku.core.view.interfaces.IVideo;
   import flash.net.URLLoader;
   import flash.events.NetStatusEvent;
   import flash.events.AsyncErrorEvent;
   import flash.net.NetConnection;
   import flash.net.NetStream;
   import com.youku.utils.DelayTimer;
   import flash.events.Event;
   import flash.events.IOErrorEvent;
   import flash.events.SecurityErrorEvent;
   import flash.net.URLRequest;
   import com.adobe.json.JSON;
   import com.youku.interfaces.*;
   import com.youku.core.view.events.BaseVideoEvent;
   import com.youku.core.CoreContext;
   import com.youku.data.PlayerConstant;
   import com.youku.PlayerConfig;
   import com.youku.utils.PlayListUtil;
   import flash.utils.getTimer;
   import com.youku.core.model.vo.VideoSegmentData;
   
   public class RTMPVideo extends BaseVideo implements IVideo
   {
      
      public function RTMPVideo() {
         super();
         _closed = true;
         _duration = 0;
         _lastCanSeekTime = 0;
         _jumpT = 0;
         _storeVolume = 0;
         _started = false;
         _waitPause = false;
         _playOver = false;
         _preloadDone = false;
         _oldTotalSize = -1;
         _code2002Sent = false;
         _code3004Sent = false;
         _networkMayHaveProblem = false;
         _actionList = new Array();
         this._rtmpFileURL = "";
         this._ncConnected = false;
         _vh = 240;
         _vw = 320;
         _loadStartTime = -1;
         _loadStartSize = -1;
         _speed = 0;
         this._tempT = 0;
         this._seekPos = 0;
         this._seekTime = getTimer();
      }
      
      private var _loader:URLLoader;
      
      private var _rtmpFileURL:String;
      
      private var _tempT:Number;
      
      private var _seekPos:Number;
      
      private var _seekTime:Number;
      
      private var _connecting:Boolean = false;
      
      private var _pauseFailed:Boolean = false;
      
      private var _ncConnected:Boolean = false;
      
      override protected function createItems() : void {
         if(_nc)
         {
            _nc.removeEventListener(NetStatusEvent.NET_STATUS,this.onNcNetStatus);
            _nc.removeEventListener(AsyncErrorEvent.ASYNC_ERROR,this.onNcError);
            _nc.close();
            _nc = null;
         }
         _nc = new NetConnection();
         _nc.client = this;
         _nc.connect(null);
         _nc.addEventListener(NetStatusEvent.NET_STATUS,this.onNcNetStatus);
         _nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR,this.onNcError);
         this._ncConnected = false;
         if(_ns)
         {
            _ns.removeEventListener(NetStatusEvent.NET_STATUS,this.onNetStatus);
            setVolume(0);
            _ns.close();
            _ns = null;
         }
         _ns = new NetStream(_nc);
         _ns.bufferTime = EMPTY_BUFFER_TIME;
         _ns.inBufferSeek = true;
         _ns.backBufferTime = 600;
         _nsObj = new Object();
         _ns.client = _nsObj;
         _delayTimer = new DelayTimer(_ns,_num);
      }
      
      private function loadRTMPPath() : void {
         _closed = false;
         if(this._loader)
         {
            this._loader.removeEventListener(Event.COMPLETE,this.onLoaderComplete);
            this._loader.removeEventListener(IOErrorEvent.IO_ERROR,this.onLoaderError);
            this._loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,this.onLoaderError);
            try
            {
               this._loader.close();
            }
            catch(e:Error)
            {
            }
            this._loader = null;
         }
         this._loader = new URLLoader();
         this._loader.addEventListener(Event.COMPLETE,this.onLoaderComplete);
         this._loader.addEventListener(IOErrorEvent.IO_ERROR,this.onLoaderError);
         this._loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,this.onLoaderError);
         this._loader.load(new URLRequest(this.getFileURL(false)));
      }
      
      private function onLoaderComplete(param1:Event) : void {
         var _loc3_:Object = null;
         var _loc2_:String = this._loader.data as String;
         if(_loc2_)
         {
            _loc3_ = com.adobe.json.JSON.decode(_loc2_)[0];
            if(_videoSegment.fileId == _loc3_.fileid)
            {
               this._rtmpFileURL = "flv:" + _loc3_.fileid;
               if(_playListData.fileType == "mp4")
               {
                  this._rtmpFileURL = "mp4:" + _loc3_.fileid + ".mp4";
               }
               this.createNc(_loc3_.server);
            }
            this._connecting = true;
         }
         else
         {
            this._connecting = false;
         }
      }
      
      private function createNc(param1:String) : void {
         if(!this._connecting)
         {
            return;
         }
         if(_nc)
         {
            _nc.removeEventListener(NetStatusEvent.NET_STATUS,this.onNcNetStatus);
            _nc.removeEventListener(AsyncErrorEvent.ASYNC_ERROR,this.onNcError);
            _nc.close();
            _nc = null;
         }
         _nc = new NetConnection();
         _nc.client = this;
         _nc.addEventListener(NetStatusEvent.NET_STATUS,this.onNcNetStatus);
         _nc.removeEventListener(AsyncErrorEvent.ASYNC_ERROR,this.onNcError);
         _nc.connect("rtmpe://" + param1);
      }
      
      private function onNcNetStatus(param1:NetStatusEvent) : void {
         switch(param1.info.code)
         {
            case "NetConnection.Connect.Success":
               this._ncConnected = true;
               this.createNetStream();
               break;
            case "NetConnection.Connect.Failed":
            case "NetConnection.Connect.Closed":
               this.close();
               break;
            case "NetConnection.Connect.Rejected":
               this.onRtmpFailError();
               break;
         }
         this._connecting = false;
      }
      
      private function onNcError(param1:AsyncErrorEvent) : void {
      }
      
      public function onPlayStatus(param1:Object) : void {
      }
      
      public function onBWDone() : void {
      }
      
      private function createNetStream() : void {
         if(_ns)
         {
            _ns.removeEventListener(NetStatusEvent.NET_STATUS,this.onNetStatus);
            _ns.close();
            _ns = null;
         }
         _ns = new NetStream(_nc);
         _ns.bufferTime = EMPTY_BUFFER_TIME;
         _ns.inBufferSeek = true;
         _ns.backBufferTime = 600;
         _nsObj = new Object();
         _ns.client = _nsObj;
         _nsObj.onMetaData = function(param1:Object):void
         {
            onVideoMetaData(param1);
         };
         _ns.addEventListener(NetStatusEvent.NET_STATUS,this.onNetStatus);
         _ns.play(this._rtmpFileURL);
         if(_jumpT)
         {
            _ns.seek(_jumpT);
         }
         setVolume(0);
         try
         {
            this.removeEventListener(Event.ENTER_FRAME,this.onEnterFrameForStop);
         }
         catch(e:Error)
         {
         }
         this.addEventListener(Event.ENTER_FRAME,this.onEnterFrameForStop);
      }
      
      override protected function onVideoMetaData(param1:Object) : void {
         var _loc3_:Array = null;
         var _loc4_:* = 0;
         _isGotMetadata = true;
         _vw = !param1.width?320:param1.width;
         _vh = !param1.height?240:param1.height;
         _duration = param1.duration;
         if(_playListData.fileType == "flv" || _playListData.fileType == "hd2")
         {
            if(param1.lastkeyframetimestamp)
            {
               _lastCanSeekTime = param1.lastkeyframetimestamp;
            }
         }
         else if(_playListData.fileType == "mp4")
         {
            if((param1.seekpoints) && param1.seekpoints.length > 0)
            {
               _loc3_ = [];
               _loc4_ = 0;
               while(_loc4_ < param1.seekpoints.length)
               {
                  _loc3_.push(param1.seekpoints[_loc4_].time);
                  _loc4_++;
               }
               _loc3_.sort(Array.NUMERIC | Array.DESCENDING);
               _lastCanSeekTime = _loc3_[0];
               _lastCanSeekTime = _lastCanSeekTime + _jumpT;
            }
         }
         
         var _loc2_:BaseVideoEvent = new BaseVideoEvent(BaseVideoEvent.GOT_METADATA,{"num":this.num});
         dispatchEvent(_loc2_);
      }
      
      override protected function onNetStatus(param1:NetStatusEvent) : void {
         var _loc2_:BaseVideoEvent = null;
         var _loc3_:BaseVideoEvent = null;
         var _loc4_:String = null;
         switch(param1.info.code)
         {
            case "NetStream.Play.Start":
               onNetStreamPlayStartEvent();
               break;
            case "NetStream.Play.Stop":
               break;
            case "NetStream.Buffer.Full":
               _loc3_ = new BaseVideoEvent(BaseVideoEvent.BUFFER_FULL,{"num":this.num});
               this.dispatchEvent(_loc3_);
               this.showBuffer(false);
               if(!_started)
               {
                  _started = true;
                  _loc2_ = new BaseVideoEvent(BaseVideoEvent.PLAY_START,{"num":this.num});
                  setVolume(_storeVolume);
               }
               if(this._tempT)
               {
                  this._tempT = 0;
               }
               if(this._pauseFailed)
               {
                  _ns.pause();
                  this._pauseFailed = false;
               }
               break;
            case "NetStream.Buffer.Empty":
               _loc2_ = new BaseVideoEvent(BaseVideoEvent.BUFFER_EMPTY,
                  {
                     "num":this.num,
                     "isRealBuffer":true
                  });
               break;
            case "NetStream.Play.StreamNotFound":
               _loc2_ = new BaseVideoEvent(BaseVideoEvent.PLAY_LOAD_ERROR,{"num":this.num});
               break;
            case "NetStream.Seek.InvalidTime":
               break;
            case "NetConnection.Connect.Rejected":
               this.onRtmpFailError();
               break;
            case "NetStream.Seek.Notify":
               _loc4_ = new String(param1.info.description);
               if(_loc4_.indexOf("client-inBufferSeek") >= 0)
               {
               }
               break;
         }
         if(_loc2_)
         {
            this.dispatchEvent(_loc2_);
         }
      }
      
      private function onEnterFrameForStop(param1:Event) : void {
         var _loc2_:BaseVideoEvent = null;
         if((_ns) && (_duration) && (_ns.time >= _duration || Math.abs(_ns.time - _duration) < 0.1))
         {
            _loc2_ = new BaseVideoEvent(BaseVideoEvent.PLAY_OVER,{"num":this.num});
            this.dispatchEvent(_loc2_);
            this.removeEventListener(Event.ENTER_FRAME,this.onEnterFrameForStop);
         }
      }
      
      private function onLoaderError(param1:Event) : void {
         this._connecting = false;
         this._ncConnected = false;
      }
      
      protected function onRtmpFailError() : void {
         this.close();
         var _loc1_:BaseVideoEvent = new BaseVideoEvent(BaseVideoEvent.RTMP_FAIL_ERROR,{"num":this.num});
         dispatchEvent(_loc1_);
      }
      
      override protected function pauseVideoForLoad() : void {
         if(_waitPause)
         {
            _ns.pause();
            _waitPause = false;
            setVolume(_storeVolume);
         }
      }
      
      override public function getFileURL(param1:Boolean) : String {
         var _loc6_:String = null;
         var _loc2_:String = _num.toString(16);
         if(_loc2_.length == 1)
         {
            _loc2_ = "0" + _loc2_;
         }
         var _loc3_:* = "http://k.youku.com/player/getRtmpPath";
         _loc3_ = _loc3_ + ("/sid/" + _playListData.sid + "_" + _loc2_);
         _loc3_ = _loc3_ + ("/st/" + (_playListData.fileType == "hd2"?"flv":_playListData.fileType));
         _loc3_ = _loc3_ + ("/fileid/" + _videoSegment.fileId + "?K=");
         if(_videoSegment.key == "")
         {
            _loc3_ = _loc3_ + (_playListData.key2 + _playListData.key1);
         }
         else
         {
            _loc3_ = _loc3_ + _videoSegment.key;
         }
         if(_playListData.fileType == "flv" || _playListData.fileType == "flvhd")
         {
            _loc3_ = _loc3_ + "&hd=0";
         }
         else if(_playListData.fileType == "mp4")
         {
            _loc3_ = _loc3_ + "&hd=1";
         }
         else if(_playListData.fileType == "hd2")
         {
            _loc3_ = _loc3_ + "&hd=2";
         }
         
         
         var _loc4_:String = CoreContext.playerProxy.playerData.IkuFlag;
         _loc4_ = _loc4_ == ""?"0":_loc4_;
         _loc3_ = _loc3_ + ("&myp=" + _loc4_);
         _loc3_ = _loc3_ + ("&ts=" + int(_videoSegment.seconds));
         if(_playListData.show)
         {
            _loc3_ = _loc3_ + "&ypremium=1";
         }
         _loc3_ = _loc3_ + ("&ctype=" + PlayerConstant.CTYPE);
         _loc3_ = _loc3_ + ("&ev=" + PlayerConstant.EV);
         _loc3_ = _loc3_ + ("&token=" + _playListData.tk);
         _loc3_ = _loc3_ + ("&oip=" + _playListData.oip);
         var _loc5_:String = _playListData.sid + "_" + _videoSegment.fileId + "_" + _playListData.tk;
         _loc5_ = _loc5_ + ("_" + PlayerConfig.bctime);
         _loc6_ = PlayListUtil.getInstance().changeSize(_loc5_);
         _loc3_ = _loc3_ + ("&ep=" + PlayListUtil.getInstance().setSize(_loc5_ + "_" + _loc6_.substr(0,4)));
         return _loc3_;
      }
      
      private function showBuffer(param1:Boolean) : void {
         var _loc2_:BaseVideoEvent = null;
         if(param1)
         {
            _loc2_ = new BaseVideoEvent(BaseVideoEvent.BUFFER_EMPTY,
               {
                  "num":this.num,
                  "isRealBuffer":false
               });
         }
         else
         {
            _loc2_ = new BaseVideoEvent(BaseVideoEvent.BUFFER_FULL,{"num":this.num});
         }
         this.dispatchEvent(_loc2_);
      }
      
      private function resetSomeData() : void {
         _started = false;
         _loadStartSize = -1;
         _loadStartTime = -1;
         _oldTotalSize = -1;
         _speed = 0;
         this._tempT = 0;
      }
      
      override public function play(param1:Boolean = false) : void {
         _playOver = false;
         if((_started) && !param1 && (_ns))
         {
            _ns.pause();
            _ns.resume();
            setVolume(_storeVolume);
         }
         else
         {
            if(!param1 && (this.preloadDone) && (_waitPause))
            {
               _waitPause = false;
               return;
            }
            _waitPause = false;
            if(this._connecting)
            {
               return;
            }
            this._connecting = true;
            this.resetSomeData();
            this.dispatchEvent(new BaseVideoEvent(BaseVideoEvent.CONNECT_START));
            this.loadRTMPPath();
            if(!param1)
            {
               this.showBuffer(true);
            }
         }
         _jumpT = 0;
      }
      
      override protected function realSeek(param1:Number, param2:Boolean, param3:Boolean = false) : void {
         this._seekPos = param1;
         this._seekTime = getTimer();
         _playOver = false;
         if(param1 > _videoSegment.seconds)
         {
            param1 = _videoSegment.seconds;
         }
         if(param1 > _lastCanSeekTime && !(_lastCanSeekTime == 0))
         {
            param1 = _lastCanSeekTime;
         }
         if(this._ncConnected)
         {
            this._tempT = param1;
            _ns.seek(param1);
         }
         else
         {
            _jumpT = param1;
            if(this._connecting)
            {
               return;
            }
            this._connecting = true;
            this.resetSomeData();
            this.dispatchEvent(new BaseVideoEvent(BaseVideoEvent.CONNECT_START));
            this.loadRTMPPath();
            this.showBuffer(true);
         }
      }
      
      override public function get nsTime() : Number {
         if(!_ns)
         {
            return _jumpT;
         }
         if(this._tempT)
         {
            return this._tempT;
         }
         var _loc1_:Number = 0;
         if((_started) && _ns.time > 0)
         {
            _loc1_ = _ns.time;
         }
         else
         {
            _loc1_ = _jumpT;
         }
         return _loc1_;
      }
      
      override public function close(param1:Boolean = true) : void {
         _closed = true;
         this._ncConnected = false;
         _waitPause = false;
         _preloadDone = false;
         _started = false;
         _jumpT = 0;
         _oldTotalSize = -1;
         _loadStartSize = -1;
         _loadStartTime = -1;
         _speed = 0;
         _networkMayHaveProblem = false;
         _reconnectCount = 2;
         _reconnectURL = "";
         this._rtmpFileURL = "";
         this._tempT = 0;
         this._connecting = false;
         this._pauseFailed = false;
         this.removeEventListener(Event.ENTER_FRAME,this.onEnterFrameForStop);
         if(_ns)
         {
            setVolume(0);
            _ns.close();
         }
         if(_nc)
         {
            _nc.close();
         }
      }
      
      override public function pause() : void {
         if((_started) && (_ns))
         {
            _ns.pause();
            this._pauseFailed = false;
         }
         else
         {
            this._pauseFailed = true;
         }
      }
      
      override public function resume() : void {
         if(_ns)
         {
            _ns.pause();
            _ns.resume();
            setVolume(_storeVolume);
            _waitPause = false;
         }
         this._pauseFailed = false;
      }
      
      override public function get loadedTime() : Number {
         return this.nsTime;
      }
      
      override public function get bytesLoaded() : Number {
         return 0;
      }
      
      override public function get bytesTotal() : Number {
         return 0;
      }
      
      override public function get oldTotalSize() : Number {
         return 0;
      }
      
      override public function get loadOver() : Boolean {
         return false;
      }
      
      override public function get rtmpLoadOver() : Boolean {
         if(_ns)
         {
            if(_ns.time + _ns.bufferLength > _duration - 3)
            {
               return true;
            }
            return false;
         }
         return false;
      }
      
      override public function resetData(param1:VideoSegmentData) : void {
         _videoSegment = param1;
         this.close();
         _code2002Sent = false;
         _code3004Sent = false;
         _loadStartSize = -1;
         _loadStartTime = -1;
      }
   }
}
